from Landblock import Landblock

def convertMapChar(char):
	if(char=='a'):
		name='crate'
	elif(char=='b'):
		name='base'
	elif(char=='c'):
		name='city'
	elif(char=='d'):
		name='base0'
	elif(char=='x'):
		name='swamp'
	elif(char=='e'):
		name='reef'
	elif(char=='f'):
		name='forest'
	elif(char=='g'):
		name='castle'
	elif(char=='h'):
		name='HQ0'
	elif(char=='i'):
		name='HQ1'
	elif(char=='j'):
		name='HQ2'
	elif(char=='k'):
		name='HQ3'
	elif(char=='l'):
		name='farm'
	elif(char=='m'):
		name='mountain'
	elif(char=='n'):
		name='mine'
	elif(char=='o'):
		name='base3'
	elif(char=='p'):
		name='plain'
	elif(char=='q'):
		name='city0'
	elif(char=='r'):
		name='road'
	elif(char=='s'):
		name='shoal'
	elif(char=='t'):
		name='port'
	elif(char=='u'):
		name='city1'
	elif(char=='v'):
		name='indu'
	elif(char=='w'):
		name='water'
	elif(char=='x'):
		name='city3'
	elif(char=='y'):
		name='airport0'
	elif(char=='z'):
		name='pipe'
	elif(char=='1'):
		name='indock'
	elif(char=='2'):
		name='sand'
	elif(char=='3'):
		name='tree'
	elif(char=='4'):
		name='pipes'
	elif(char=='5'):
		name='port3'
	elif(char=='6'):
		name='port0'
	else:
		print(''.join(['char is unknown: ',char]))
		name='unknown'
	return(name)

class Grid:
	def __init__(self,fileName):
		mapFile=open(fileName)
		headerLine=mapFile.readline()#line 1 is width,height,teams
		turnOrderLine=mapFile.readline()#line2 is team turn order
		self.turnOrder=self._readTurnOrder(turnOrderLine)
		playerComputerLine=mapFile.readline()#line 3 is player or AI
		self.playerOrAI = self._readPlayerOrAI(playerComputerLine)
		self.victoryConditions= self._readVictoryConditions(mapFile.readline())#line 4 is victory conditions
		headerLinePartition=headerLine.partition(' ')
		rowColPartition=headerLinePartition[0].partition(',')
		rows=rowColPartition[0]
		columns=rowColPartition[2].replace('\n','')
		rows=int(rows)
		columns=int(columns)
		self.rows=rows
		self.columns=columns
		self.teams=int(headerLinePartition[2])
		grid=[]
		row=0
		for row in range(0,rows):
			line = mapFile.readline()
			grid.append([])
			charLine=list(line)
			for column in range(columns):
				char=convertMapChar(charLine[column])
				#print(''.join([charLine[column],' -> ',char]))
				grid[row].append(Landblock(row,column,char))
		prePlacedUnitsCount=int(mapFile.readline())
		prePlacedUnits=[]
		for counter in range(0,prePlacedUnitsCount):
			prePlacedUnits.append(mapFile.readline().replace('\n',''))
		self.prePlacedUnits=prePlacedUnits
		text = {}
		line = mapFile.readline()
		while line:
			s = line.split(",")
			restOfLine = ",".join(s[1:])
			if restOfLine == "":
				restOfLine = None
			text[s[0]]=restOfLine
			line = mapFile.readline()
		self.text = text
		self.grid=grid
		return
	
	def getVictoryConditions(self):
		'''
		returns the list of victory conditions
		this is a list of tuples formatted: (team,objective type,target,event)
		where objective type is one of
			K - kill enemy team (target is enemy team #)
			C - capture team HQ (target is enemy team #)
			M - move to position (target is position tuple (row,col)
			S - survive [target] number of turns (target is # of turns)
		event is one of 
			W - win. ends level with [team] as winner
			T# - displays text specified (where # is a number) e.g. T2
		'''
		return self.victoryConditions
	def getTextForTurn(self,turnNumber):
		if turnNumber in self.text:
			return self.text[turnNumber]
		return None
	def getTextForEvent(self,eventId):
		if eventId in self.text:
			return self.text[eventId]
		return None
	def getRows(self):
		return(self.rows)
	def getColumns(self):
		return(self.columns)
	def getPrePlacedUnits(self):
		return(self.prePlacedUnits)
	def getCell(self,row,column):
		return(self.grid[row][column])
	def setCell(self,row,column,landblock):
		self.grid[row][column]=landblock
	def getCells(self):
		cells=[]
		for rowList in self.grid:
			for columnVal in rowList:
				cells.append(columnVal)
		return(cells)
	def validRow(self,row):
		if((0<=row) and (row<self.getRows())):
			return(True)
		else:
			return(False)
	def validCol(self,col):
		if((0<=col) and (col<self.getColumns())):
			return(True)
		else:
			return(False)
	
	def _readVictoryConditions(self,text):
		conditions = []
		lastOpenParens=[]
		teamConditions=[]
		for i in range(0,len(text)):
			if text[i]=="(":
				lastOpenParens.append(i)
			if text[i]==")":
				start=lastOpenParens.pop()
				if len(lastOpenParens)==0:#end of team tuple
					teamConditions.append(text[start+1:i])#the contents of the team tuple
		for teamConditionText in teamConditions:
			team = int(teamConditionText[0])
			conditionStrings = []
			lastOpenParens=[]
			conditionStringGroups = []
			for i in range(0,len(teamConditionText)):
				if teamConditionText[i] in ["[","]"] and len(conditionStrings)>0:
					conditionStringGroups.append(conditionStrings)
					conditionStrings = []
				if teamConditionText[i]=="(":
					lastOpenParens.append(i)
				if teamConditionText[i]==")":
					start=lastOpenParens.pop()
					if len(lastOpenParens)==0:#end of team tuple
						conditionStrings.append(teamConditionText[start+1:i])#the contents of the team tuple
			for group in conditionStringGroups:
				groupConditions = []
				winning = False
				for condition in group:
					s = condition.split(",")
					objective = s[0]
					target = None
					if objective in ["K","C","S"]:
						target = int(s[1])
						action = s[2]
						groupConditions.append((team,objective,target,action))
					if objective == "M":
						if len(s)==4:
							action = s[3]
							fuzz = 0
						else:
							fuzz = int(s[3])
							action = s[4]
						target = (int(s[1]),int(s[2]),fuzz)
						groupConditions.append((team,objective,target,action))
					if action == "W":
						winning = True
				conditions.append((groupConditions,winning))
		return conditions
				
				
	def _readTurnOrder(self,text):
		splitText = text.split(",")
		order = []
		for value in splitText:
			order.append(int(value.strip()))
		return order
	
	def _readPlayerOrAI(self,text):
		splitText = text.split(",")
		players = []
		for value in splitText:
			players.append((value.strip()=="C"))
		return players

	def __repr__(self):
		llist=[]
		for rowList in self.grid:
			subList=[]
			for columnVal in rowList:
				subList.append(str(columnVal))
				subList.append(' , ')
			subList.append('\n')
			llist.append(''.join(subList))
		return(''.join(llist))
